import React from 'react'
import PropTypes from 'prop-types'
import Component, { mapStateToProps, mapDispatchToProps } from '@components/Component'
import { connect } from 'react-redux'
import { Form, Input, Button, Select, Modal, message } from 'antd'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import style from './BookRoom.module.less'
import BookRoomSelector from '@components/BookRoomSelector/Index'
import { ApproveBlock, Header, Line, Cell, Split, Footer, TextLine, TextCell, TitleLine } from '@components/ApprovePre/Approve'
import FileCreator from '@components/FileCreator/Index'
import moment from 'moment'
import { defaultProcedure } from '@src/assets/js/config'

const { Item } = Form
const { Option } = Select
const { confirm } = Modal

class BookRoom extends Component {
  state = {
    selectorVisible: false,
    list: [],
    modifyIndex: '',
    justModifyBookInfo: false,
    fileCreatorVisible: false,
    bizid: '',
    fileMap: {},
    fileTemplates: [],
    fileBizid: '',
    dictionaries: {} // 枚举字典
  }

  formRef = React.createRef()

  // 获取文件列表，并格式化文件映射对象
  getFile () {
    this.$getFileList(this.props.caseDetail.id)
      .then(() => {
        this.formatFileMap()
      })
  }

  // 获取庭室预约信息
  getList () {
    if (!this.props.caseDetail.id) {
      return setTimeout(() => {
        this.getList()
      }, 100)
    }
    const hide = message.loading('获取案件已约庭信息', 120)
    this.$get(`/api/xapc/casehearingroombook/${this.props.caseDetail.id}`)
      .then(res => {
        hide()
        if (res.status === 1) {
          this.getFile()
          this.setState({
            list: res.data.map(li => {
              const date = moment(li.begin_datetime * 1000).format('YYYY-MM-DD')
              const start = moment(li.begin_datetime * 1000).format('HH:mm')
              const end = moment(li.end_datetime * 1000).format('HH:mm')
              return {
                editing: false,
                id: li.id,
                operator: li.operator,
                bookInfo: {
                  room_name: li.hearingroom_name,
                  room_id: li.hearingroomid,
                  date,
                  start_time: start,
                  end_time: end
                },
                use: li.use,
                remark: li.remark,
                status: li.status
              }
            })
          })
        } else {
          message.warning(res.message)
        }
      })
      .catch(() => hide())
  }

  // 添加预约庭室
  addBook () {
    const list = this.state.list.slice()
    list.push({
      editing: true,
      creator: this.props.userInfo.realname,
      bookInfo: null,
      use: '开庭',
      remark: '',
      status: 1
    })
    this.setState({
      list,
      modifyIndex: 0
    })
  }

  // 修改预约庭室信息
  modifyBookInfo (data) {
    const { list, modifyIndex } = this.state
    const l = list.slice()
    const o = {
      ...l[modifyIndex]
    }
    o.bookInfo = data

    if (!this.state.justModifyBookInfo) {
      l[modifyIndex].bookInfo = data
      this.setState({
        selectorVisible: false,
        list: l
      }, () => {
        this.formRef.current.setFieldsValue({
          bookInfo: data
        })
      })
    } else {
      this.setState({
        modifyIndex: '',
        selectorVisible: false
      }, () => {
        this.updateBookRequest(o)
      })
    }
  }

  // 变更预约，改变状态为编辑
  changeBook (i) {
    const list = this.state.list.slice()
    list[i].editing = true
    this.setState({
      list,
      modifyIndex: String(i)
    })
  }

  // 取消编辑
  cancelEdit (i) {
    const list = this.state.list.slice()
    const o = list[i]
    if (o.id) {
      o.editing = false
    } else {
      list.splice(i, 1)
    }
    this.setState({
      list,
      modifyIndex: ''
    })
  }

  // 确定编辑
  decideEdit (i) {
    this.setState({
      modifyIndex: i
    }, () => {
      this.formRef.current.submit()
    })
  }

  // 确定提交输入
  submitInput (data) {
    const list = this.state.list.slice()
    const o = list[this.state.modifyIndex]
    const newData = {
      ...data,
      bookInfo: o.bookInfo
    }
    if (newData.id) {
      this.updateBookRequest(newData)
    } else {
      this.addBookRequest(newData)
    }
  }

  // 确认添加预约庭室
  addBookRequest (o) {
    const hide = message.loading('预约庭室中', 120)
    const b = o.bookInfo
    this.$post('/api/xapc/hearingroombook', {
      hearingroomid: b.room_id,
      begin_datetime: Math.floor(moment(`${b.date} ${b.start_time}`).valueOf() / 1000),
      end_datetime: Math.floor(moment(`${b.date} ${b.end_time}`).valueOf() / 1000),
      caseid: this.props.caseDetail.id,
      remark: o.remark,
      use: o.use,
      status: o.status
    }).then(res => {
      hide()
      if (res.status === 1) {
        this.setState({
          modifyIndex: ''
        }, () => {
          this.getList()
        })
      } else {
        message.warning(res.message)
      }
    }).catch(() => hide())
  }

  // 确定更改预约庭室
  updateBookRequest (o) {
    const hide = message.loading(o.status ? '更改预约中' : '取消预约中', 120)
    const b = o.bookInfo
    this.$put(`/api/xapc/hearingroombook/${o.id}`, {
      hearingroomid: b.room_id,
      begin_datetime: Math.floor(moment(`${b.date} ${b.start_time}`).valueOf() / 1000),
      end_datetime: Math.floor(moment(`${b.date} ${b.end_time}`).valueOf() / 1000),
      caseid: this.props.caseDetail.id,
      remark: o.remark,
      use: o.use,
      status: o.status
    }).then(res => {
      hide()
      if (res.status === 1) {
        this.setState({
          modifyIndex: '',
          justModifyBookInfo: false
        }, () => {
          this.getList()
        })
      } else {
        message.warning(res.message)
      }
    }).catch(() => hide())
  }

  // 取消预约
  cancelBook (i) {
    const list = this.state.list.slice()
    const o = list[i]
    const b = o.bookInfo
    confirm({
      icon: <ExclamationCircleOutlined />,
      content: `您确定要取消 ${b.room_name}（${b.date} ${b.start_time} ～ ${b.end_time}） 的预约吗？`,
      onOk: () => {
        o.status = 0
        this.updateBookRequest(o)
      }
    })
  }

  // 生成文书
  createFile (data) {
    const fileTemplates = []
    const isNormal = this.props.caseDetail.procedure === defaultProcedure
    fileTemplates.push('开庭通知书（' + (isNormal ? '普通' : '简易') + '）')
    fileTemplates.push('出庭签到表')
    fileTemplates.push('变更开庭通知书（' + (isNormal ? '普通' : '简易') + '）')
    fileTemplates.push('取消开庭通知书（' + (isNormal ? '普通' : '简易') + '）')
    fileTemplates.push('庭审笔录模板（' + (isNormal ? '普通' : '简易') + '）')
    fileTemplates.push('当事人意见反馈表')
    this.setState({
      fileCreatorVisible: true,
      fileTemplates,
      fileBizid: data.id
    })
  }

  // 创建文书请求
  createFileRequest (d) {
    const hide = message.loading('生成文书中', 120)
    this.$post('/api/vendor/case/file', {
      caseid: this.props.caseDetail.id,
      bizid: this.state.fileBizid,
      filename: d.files
    }).then(res => {
      hide()
      if (res.status === 1) {
        this.getFile()
      } else {
        message.warning(res.message)
      }
    }).catch(() => hide())
  }

  // 生成文件映射对象
  formatFileMap () {
    const map = {}
    this.state._fileList.forEach(li => {
      if (li.bizid) {
        if (!map[li.bizid]) {
          map[li.bizid] = []
        }
        map[li.bizid].push(li)
      }
    })
    this.setState({
      fileMap: map
    })
  }

  hideBookRoomSelector () {
    this.setState({
      selectorVisible: false
    })
    if (this.state.justModifyBookInfo) {
      this.setState({
        justModifyBookInfo: false,
        modifyIndex: ''
      })
    }
  }

  // 获取枚举的字典值
  getDictionary () {
    this.$get('/api/xapc/dictionary', {
      types: '庭室用途'
    }).then(res => {
      if (res.status === 1) {
        // 设置枚举字典
        const dictionaries = this.formatDictionaries(res.data)
        this.setState({
          dictionaries
        })
      } else {
        message.error(res.message)
      }
    })
  }

  // 格式化枚举字典
  formatDictionaries (dictionaries = []) {
    const result = {}
    dictionaries.forEach(d => {
      result[d.type] = d.list
    })
    return result
  }

  componentDidMount () {
    this.getDictionary()
    this.getList()
  }

  // 渲染约庭列表
  renderList () {
    return this.state.list.map((li, i) => {
      if (li.editing) {
        return this.renderInputBlock(li, i)
      } else {
        return this.renderTextBlock(li, i)
      }
    })
  }

  // 渲染输入块
  renderInputBlock (li, i) {
    const { bookInfo: b } = li
    let info = ''
    if (b && b.room_name && b.date && b.start_time && b.end_time) {
      info = `${b.room_name}（${b.date} ${b.start_time} ～ ${b.end_time}）`
    }
    const useList = this.state.dictionaries['庭室用途'] || []
    return (
      <div key={i} className={style.block}>
        <Form name={`create-book-room-${i}`} ref={this.formRef} initialValues={li} onFinish={v => this.submitInput(v)}>
          <Item noStyle name='id'><span /></Item>
          <ApproveBlock>
            <Header title='预约庭室' />
            <Line>
              <Cell>
                <Item label='发起人'>{this.props.userInfo.realname}</Item>
              </Cell>
              <Split />
              <Cell style={{ width: '65%' }}>
                <Item label='约庭信息' name='bookInfo' rules={[{ required: true, message: '庭室信息不能为空' }]}>
                  <span>
                    <span>{info}</span>
                    <Button type='primary' onClick={() => this.setState({ selectorVisible: true, modifyInfo: null, modifyIndex: i })}>选择</Button>
                  </span>
                </Item>
              </Cell>
            </Line>
            <Line>
              <Cell>
                <Item label='庭室用途' name='use' rules={[{ required: true, message: '庭室用途' }]}>
                  <Select placeholder='请选择庭室用途'>
                    {useList.map((li, i) => (
                      <Option key={i} value={li.value}>{li.title}</Option>
                    ))}
                  </Select>
                </Item>
              </Cell>
            </Line>
            <Footer>
              <Line>
                <Cell style={{ width: '65%' }}>
                  <Item label='备注' name='remark' style={{ marginBottom: 0 }}>
                    <Input placeholder='请输入备注' style={{ width: '100%' }} />
                  </Item>
                </Cell>
                <Split />
                <Cell style={{ textAlign: 'right' }}>
                  <Button onClick={() => this.cancelEdit(i)}>取消</Button>
                  <Button type='primary' onClick={() => this.decideEdit(i)}>确认</Button>
                </Cell>
              </Line>
            </Footer>
          </ApproveBlock>
        </Form>
      </div>

    )
  }

  // 渲染文书列表
  renderFileList (list) {
    if (list.length === 0) {
      return <span>暂无</span>
    }
    return list.map((li, i) => {
      return (<span key={i} className={style.file} onClick={() => this.$readerFileById(li.id, this.props.caseDetail.id)}>{li.title}.pdf</span>)
    })
  }

  // 渲染预约庭室信息块
  renderTextBlock (li, i) {
    const { bookInfo: b } = li
    const { editable } = this.props
    return (
      <div key={i} className={style.block}>
        <ApproveBlock>
          <Header title='预约庭室' />
          {li.status === 0 ? <div className={style['block-cancel']}>已取消</div> : null}
          {li.status === 2 ? <div className={style['block-cancel']}>已变更</div> : null}
          <TextLine>
            <TextCell>发起人：{li.operator}</TextCell>
            <Split />
            <TextCell style={{ width: '65%' }}>
              <span>约庭信息{b.room_name}（{b.date} {b.start_time} ～ {b.end_time}）</span>
              {li.status === 1 && !this.state.modifyIndex && editable ? (
                <span className={`${style['link-btn']} ${style.ml16}`} onClick={() => this.setState({ selectorVisible: true, modifyInfo: null, modifyIndex: i, justModifyBookInfo: true })}>修改</span>
              ) : null}
            </TextCell>
          </TextLine>
          <TextLine>
            <TextCell>庭室用途：{li.use}</TextCell>
            <Split />
            <TextCell style={{ width: '65%' }}>备注：{li.remark}</TextCell>
          </TextLine>
          <TitleLine title='文书打印' />
          <TextLine>
            <TextCell style={{ width: '100%' }}>
              {this.renderFileList(this.state.fileMap[li.id] || [])}
            </TextCell>
          </TextLine>
          <Footer>
            <Line>
              <Cell style={{ textAlign: 'right', width: '100%' }}>
                {li.status === 1 ? (
                  <>
                    <Button disabled={!editable || this.state.modifyIndex !== ''} onClick={() => this.cancelBook(i)}>取消预约</Button>
                    <Button disabled={!editable || this.state.modifyIndex !== ''} onClick={() => this.changeBook(i)}>变更预约</Button>
                  </>
                ) : null}
                <Button type='primary' disabled={!editable || this.state.modifyIndex !== ''} onClick={() => this.createFile(li)}>生成文书</Button>
              </Cell>
            </Line>
          </Footer>
        </ApproveBlock>
      </div>
    )
  }

  renderAddBtn () {
    const { editable } = this.props
    if (!editable) {
      return false
    }
    return (
      <div className={style['add-button']}>
        <Button type='dashed' disabled={this.state.modifyIndex !== ''} block onClick={() => { this.addBook() }}>+ 添加预约</Button>
      </div>
    )
  }

  render () {
    // return this.renderInputBlock()
    // return this.renderTextBlock()
    const { modifyIndex, list } = this.state
    const modifyInfo = modifyIndex !== '' ? list[modifyIndex].bookInfo : undefined
    return (
      <div>
        <FileCreator visible={this.state.fileCreatorVisible} bizid={this.state.fileBizid} fileList={this.state.fileTemplates} hide={() => this.setState({ fileCreatorVisible: false, fileTemplates: [] })} onChange={d => this.createFileRequest(d)} />
        <BookRoomSelector visible={this.state.selectorVisible} caseDetail={this.props.caseDetail} value={modifyInfo} hide={() => this.hideBookRoomSelector()} onChange={v => this.modifyBookInfo(v)} />
        {this.renderList()}
        {this.renderAddBtn()}
      </div>
    )
  }
}

BookRoom.propTypes = {
  caseDetail: PropTypes.object,
  editable: PropTypes.bool
}
BookRoom.defaultProps = {
  caseDetail: {},
  editable: false
}

const mapState = mapStateToProps(function (state) {
  return {
    userInfo: state.basic.userInfo
  }
})

const mapDispatch = mapDispatchToProps(function (dispatch) {
  return {

  }
})

export default connect(mapState, mapDispatch)(BookRoom)
